#include <iostream>
#include <string>
#include <vector>
#include <mariadb/mysql.h>

#define HOST "127.0.0.1"
#define PORT 3306
#define USER "root"
#define PASSWORD "Xsc.200411"
#define DB "gobang"


int main()
{
    // 1.获取mysql操作句柄
    MYSQL *mysql = mysql_init(nullptr);
    if(mysql == nullptr) {
        std::cerr << "mysql_init error-> " << mysql_error(mysql) << std::endl;;
        return -1;
    }    

    // 2.连接mysql服务器
    if(!mysql_real_connect(mysql, HOST, USER, PASSWORD, DB, PORT, nullptr, 0)) {
        std::cerr << "connect mysql server error-> " << mysql_error(mysql) << std::endl;
        return -1;
    }

    // 3.设置客户端字符集
    if(!mysql_set_character_set(mysql, "utf8mb4_general_ci")) {
        std::cerr << "mysql_set_character_set error-> " << mysql_error(mysql) << std::endl;
        return -3;
    }

    // 4.选择要操作的数据库
    mysql_select_db(mysql, DB);

    // 5.执行sql语句
    std::string sql = "select * from test_stu";
    int ret = mysql_query(mysql, sql.c_str());
    if(ret != 0) {
        // mysql_query返回值等于0表示sql语句执行成功
        std::cout << sql << std::endl;
        std::cout << mysql_error(mysql) << std::endl;
        // 此时不能直接return，避免资源泄露，要先关闭连接，销毁句柄
        mysql_close(mysql);
    }

    // 6.查询并获取结果集到本地
    MYSQL_RES *res = mysql_store_result(mysql);
    if(res == nullptr) {
        std::cout << "mysql_store_result error-> " << mysql_error(mysql) << std::endl;
        return -5;
    }

    // 7.获取行数和列数
    int row = mysql_num_rows(res);
    int col = mysql_num_fields(res);

    // 8.遍历结果集
    for(int i=0; i<row; i++) {
        // 一行一行取出
        MYSQL_ROW s = mysql_fetch_row(res);
        for(int j=0; j<col; j++) {
            std::cout << s[j] << "\t";
        }
        std::cout << std::endl;
    }
    // 9.释放结果集
    mysql_free_result(res);
    // 10.关闭句柄
    mysql_close(mysql);

    return 0;
}


int mysql_query_add(MYSQL *mysql)
{
    //std::string sql1 = "insert into test_stu (name, age, chinese, english, math) values ('张三', 18, 72.1, 88.8, 99.9);";
    //std::string sql2 = "insert into test_stu (name, age, chinese, english, math) values ('李四', 28, 11.1, 32.4, 60.0);";
    //std::string sql3 = "insert into test_stu (name, age, chinese, english, math) values ('王五', 9, 100, 100, 100);";
    //std::string sql1 = "update test_stu set chinese=0, english=0, math=0 where id=1;";
    std::string sql1 = "delete from test_stu where id=1;";
    std::vector<std::string> sqls({sql1});
    for(auto sql : sqls) {
        int ret = mysql_query(mysql, sql.c_str());
        if(ret != 0) {
            std::cout << sql << std::endl;
            std::cout << mysql_error(mysql) << std::endl;
            mysql_close(mysql);
            return -4;
        }
    }
    return 0;
}

int mysql_query_get(MYSQL *mysql)
{
    std::string sql = "select * from test_stu";
    int ret = mysql_query(mysql, sql.c_str());
    if(ret != 0) {
        std::cout << sql << std::endl;
        std::cout << mysql_error(mysql) << std::endl;
        mysql_close(mysql);
        return -4;
    }
    return 0;
}

int main1()
{
    // 1.获取mysql操作句柄
    MYSQL *mysql = mysql_init(nullptr);
    if(mysql == nullptr) {
        std::cerr << "mysql_init error-> " << mysql_error(mysql) << std::endl;;
        return -1;
    }    

    // 2.连接mysql服务器
    if(!mysql_real_connect(mysql, HOST, USER, PASSWORD, DB, PORT, nullptr, 0)) {
        std::cerr << "mysql_real_connect error-> " << mysql_error(mysql) << std::endl;
        return -2;
    }
    
    // 3.设置客户端字符集
    if(!mysql_set_character_set(mysql, "utf8mb4_general_ci")) {
        std::cerr << "mysql_set_character_set error-> " << mysql_error(mysql) << std::endl;
        return -3;
    }

    // 4.选择要操作的数据库
    mysql_select_db(mysql, DB);

    // 5.执行sql语句 ---增删改直接结束，查询sql还需要继续向下执行
    //mysql_query_add(mysql);
    mysql_query_get(mysql);

    // 6.查询并获取结果集到本地
    MYSQL_RES *res = mysql_store_result(mysql);
    if(res == nullptr) {
        std::cout << "mysql_store_result error-> " << mysql_error(mysql) << std::endl;
        return -5;
    }

    // 7.获取行数和列数
    int row = mysql_num_rows(res);
    int col = mysql_num_fields(res);

    // 8.遍历结果集
    for(int i=0; i<row; i++) {
        // 一行一行取出
        MYSQL_ROW s = mysql_fetch_row(res);
        for(int j=0; j<col; j++) {
            std::cout << s[j] << "\t";
        }
        std::cout << std::endl;
    }
    // 9.释放结果集
    mysql_free_result(res);
    // 9.关闭句柄
    mysql_close(mysql);
    return 0;
}